package org.brisling.service.auth.shiro;

import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.brisling.domain.sysman.Users;
import org.brisling.repository.sysman.inf.UsersRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ShiroRealm extends AuthorizingRealm{

	@Autowired
	private UsersRepo userRepo;
	
	@Autowired
	private ShiroSecurityService shiroSecurityService;
	
	private final static Logger log = Logger.getLogger(ShiroRealm.class);
	
	public ShiroRealm(){
		setName("ShiroRealm"); //This name must match the name in the User class's getPrincipals() method
		HashedCredentialsMatcher hashedCredentialsMatcher= new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
        setCredentialsMatcher(hashedCredentialsMatcher);
	}
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// TODO Auto-generated method stub
		Long userId = (Long) principals.fromRealm(getName()).iterator().next();
        Users user = userRepo.findOne(userId);
        if( user != null ) {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            
            List<String> permissionList = Arrays.asList("a","b","c");
            
            List<String> permissionadmin = Arrays.asList("user:manage","user:edit","c");
            
            if(user.getUsername().compareTo("admin")==0)
            	info.addStringPermissions(permissionadmin);
            else
            	info.addStringPermissions(permissionList );
           
            return info;
        } else {
            return null;
        }
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		// TODO Auto-generated method stub
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		
		
		String _salt = shiroSecurityService.generateSalt();
		
        Users user = userRepo.findByNameOrLoginName(token.getUsername(), token.getUsername());
        
        
        
        
        if( user != null ) {
        	if(user.getPassword_salt()!=null||user.getPassword_salt().trim().length()>0)
        		_salt = user.getPassword_salt();
        	
        	
        	Object _password =new SimpleHash(Sha256Hash.ALGORITHM_NAME,token.getCredentials(),ByteSource.Util.bytes(user.getName()+user.getId()+_salt),1);
        	
            if(log.isDebugEnabled()){
            	log.debug("password-salt:" + _salt);
            	log.debug("password:"+_password);
            }
        	SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getId(), user.getPassword(), getName());
        	info.setCredentialsSalt(ByteSource.Util.bytes(user.getName()+user.getId()+user.getPassword_salt()));
        	return info;
        } else {
            return null;
        }
	}
	
	

}
